package com.example.demo.algorithm.lesson.basic.class3;

import java.util.Arrays;

/**
 * @author liweizhi
 * @date 2020/5/6
 */
public class MergeSort {
    public static void sort1(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process(arr, 0, arr.length - 1);
    }

    public static void process(int[] arr, int left, int right) {
        if (left == right) {
            return;
        }
        int mid = left + ((right - left) >> 1);
        process(arr, left, mid);
        process(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }

    public static void merge(int[] arr, int left, int mid, int right) {
        int[] helper = new int[right - left + 1];
        int p1 = left;
        int p2 = mid + 1;
        int i = 0;
        while (p1 <= mid && p2 <= right) {
            helper[i++] = arr[p1] > arr[p2] ? arr[p2++] : arr[p1++];
        }
        while (p1 <= mid) {
            helper[i++] = arr[p1++];
        }
        while (p2 <= right) {
            helper[i++] = arr[p2++];
        }
        for (i = 0; i < helper.length; i++) {
            arr[left + i] = helper[i];
        }
    }

    public static void sort2(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        int mergeSize = 1;
        int left, mid, right;
        while (mergeSize < arr.length) {
            left = 0;
            while (left < arr.length) {
                mid = left + mergeSize - 1;
                if (mid >= arr.length) {
                    break;
                }
                right = Math.min(mid + mergeSize, arr.length - 1);
                merge(arr, left, mid, right);
                left = right + 1;
            }
            mergeSize <<= 1;
        }
    }

    public static void main(String[] args) {
        int[] arr = {5, 4, 3, 8, 2};
//        sort1(arr);
        sort2(arr);
        System.out.println(Arrays.toString(arr));
    }
}
